import { Options } from './options'
import { DefinePlugin } from 'webpack'
import { parse } from './parser'
import { generateDefines, generateDts } from './generate'
import { pickBy } from 'lodash-es'

export interface PluginOptions extends Options {
  /**
   * @default 'src/typings/env.d.ts'
   */
  outputDts?: string
  /**
   * support 'global', 'process.env', 'import.meta.env'
   * @default ['global','process.env','import.meta.env']
   */
  dtsTarget?: string[]
  onDotenvGenerate?: (env: Record<string, any>) => void | Record<string, any>
}

export default class Dotenv extends DefinePlugin {
  constructor(options: PluginOptions = {}) {
    options.outputDts = options.outputDts || 'src/typings/env.d.ts'
    options.dtsTarget = options.dtsTarget || ['global', 'process.env', 'import.meta.env']

    let env = parse(options)
    env = options.onDotenvGenerate?.(env) || env
    generateDts(env, options)

    const defines = pickBy(generateDefines(env), (_, key) => !key.includes('['))
    const replacements: Record<string, string> = {}

    for (const target of options.dtsTarget!) {
      switch (target) {
        case 'global':
          Object.assign(replacements, defines)
          break
        default:
          Object.assign(
            replacements,
            Object.fromEntries(
              Object.entries(defines).map((key, value) => [`${target}.${key}`, value])
            )
          )
          break
      }
    }

    super(replacements)
  }
}
